﻿using Ndns.Packet.Abstractions;
using System;

namespace Ndns.ServerHost.Abstractions.Services
{
    public delegate void CacheCompactCallback(int removalCount, int survivalCount);

    public interface ICacheService : IDisposable
    {
        DnsQueryAnswers Get(DnsHostName hostName, DnsRecordType t, DnsClass c);

        void Set(DnsHostName hostName, DnsRecordType t, DnsClass c, DnsQueryAnswers answers, CachePriority priority);

        void Compact(double percentage);

        void AttachCompactCallback(CacheCompactCallback callback);

        void AttachExpirationCallback(CacheCompactCallback callback);
    }

    public enum CachePriority
    {
        Low,
        Normal,
        High,
    }

    public static class CacheServiceExtensions
    {
        public static DnsQueryAnswers Get(this ICacheService cache, DnsQuery query)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            return cache.Get(query.HostName, query.Type, query.Class);
        }

        public static void Set(this ICacheService cache, DnsHostName hostName, DnsRecordType t, DnsClass c, DnsQueryAnswers answers)
        {
            cache.Set(hostName, t, c, answers, CachePriority.Normal);
        }
        public static void Set(this ICacheService cache, DnsQuery query, DnsQueryAnswers answers)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            cache.Set(query.HostName, query.Type, query.Class, answers, CachePriority.Normal);
        }
        public static void Set(this ICacheService cache, DnsQuery query, DnsQueryAnswers answers, CachePriority priority)
        {
            if (query == null)
            {
                throw new ArgumentNullException(nameof(query));
            }

            cache.Set(query.HostName, query.Type, query.Class, answers, priority);
        }
    }
}
